//
//  KZGCD.swift
//  KZSwiftMoudel
//
//  Created by 朱凯 on 2018/5/8.
//  Copyright © 2018年 JooKey. All rights reserved.
//

import Foundation
import UIKit

// MARK: ----------- * 全局函数 * -----------

// MARK: ------ lock 模拟oc中的synchronized
func synchronized(_ lockObj: AnyObject, _ clouse: ()->Void) {
    objc_sync_enter(lockObj)
    defer {
        objc_sync_exit(lockObj)
    }
    clouse()
}

// MARK: ------ 基于GCD实现简单的延迟调用和取消调用的任务
typealias KZDelayTask = (_ cancel: Bool) -> Void
// 延迟调用任务
func delay(deadline: TimeInterval, execute: @escaping ()->Void) -> KZDelayTask {
    
    // 内嵌方法
    func delayExecute(_ task: @escaping ()->Void) {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+deadline, execute: task)
    }
    
    // 创建一个局部变量用于存储任务是否被取消
    var task: (() -> Void)? = execute
    let result: KZDelayTask = {
        cancel in
        if cancel == false {
            DispatchQueue.main.async(execute: task ?? {})
        } else {
            print("任务被取消")
        }
        task = nil
    }
    
    delayExecute {
        result(false)
    }
    
    return result
}
// 取消某个延迟调用的任务
func cancelDelay(task: KZDelayTask) {
    task(true)
}

// MARK: ------ 基于Mirror实现Object-c的KVC效果
func valueFrom(_ obj: Any, forKey key: String) -> Any? {

    let mirror = Mirror(reflecting: obj)
    for child in mirror.children {
        let (targetKey, targetValue) = (child.label, child.value)
        if targetKey == key {
            return targetValue
        }
    }
    return nil
}

// MARK: ------ 随机数
func random(in range: Range<Int>) -> Int {
    let count = UInt32(range.count)
    return Int(arc4random_uniform(count)) + range.lowerBound
}
func random(in range: CountableClosedRange<Int>) -> Int {
    let count = UInt32(range.count)
    return Int(arc4random_uniform(count)) + range.lowerBound
}



// MARK: ------ 打印
func kzPrint(_ message: Any,
             file: String = #file,
             method: String = #function,
             line: Int = #line) {
    #if DEBUG_DETAIL
    print("~file: \((file as NSString).lastPathComponent)[~line: \(line)] \n method: \(method) \n message: \(message)")
    #elseif DEBUG
    print(message)
    #endif
}


// MARK: ------ 局部代码块
func local(_ clouse:()->()) {
    clouse()
}

